package web.stu.controller;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import web.stu.common.ErrorCode;
import web.stu.config.Result;
import web.stu.exception.BusinessException;
import web.stu.model.dto.clazz.ClassAddStudentsRequest;
import web.stu.model.dto.clazz.ClassDTO;
import web.stu.model.entity.User;
import web.stu.model.enums.UserRoleEnum;
import web.stu.model.vo.ClassVO;
import web.stu.model.vo.UserVO;
import web.stu.service.ClassService;
import web.stu.service.UserService;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.List;

/**
 * 班级管理控制器
 * 
 * <p>提供班级相关的CRUD操作，包括班级创建、修改、删除、查询等功能，
 * 以及班级与学生关联管理。</p>
 * 
 * @author 系统开发者
 * @version 1.0
 * @since 2025-05-29
 */
@Slf4j
@RestController
@RequestMapping("/class")
@Api(value = "班级的管理模块", tags = "班级模块")
public class ClassController {

    @Resource
    private ClassService classService;

    @Resource
    private UserService userService;

    /**
     * 获取所有班级列表
     * @return 包含所有班级信息的Result对象
     * @apiNote 返回的班级列表不包含学生信息
     */
    @GetMapping("/list")
    @ApiOperation(value = "获取所有班级列表", notes = "获取系统中所有班级的基本信息列表")
    public Result<List<ClassVO>> listAllClasses() {
        List<ClassVO> classes = classService.listAllClasses();
        return Result.success(classes);
    }

    /**
     * 班级分页查询接口
     * @param classDTO 班级查询条件DTO，包含分页参数和查询条件
     * @return 包含班级分页列表的Result对象
     * @apiNote 返回的班级列表不包含学生详细信息
     */
    @PostMapping("/page")
    @ApiOperation(value = "班级分页查询", notes = "根据条件分页查询班级信息")
    public Result<Page<ClassVO>> pageClasses(@RequestBody ClassDTO classDTO) {
        Page<ClassVO> page = classService.pageClasses(classDTO);
        return Result.success(page);
    }

    /**
     * 添加班级接口
     * @param classDTO 班级信息DTO，包含班级名称、专业等基本信息
     * @param request HTTP请求对象，用于获取会话信息
     * @return 空Result对象表示操作成功
     * @throws BusinessException 如果数据验证失败或用户无权限会抛出异常
     * @apiNote 仅管理员可访问
     */
    @PostMapping("/add")
    @ApiOperation(value = "添加班级", notes = "添加一个新的班级到系统，仅管理员可访问")
    public Result<Void> addClass(@RequestBody ClassDTO classDTO, HttpServletRequest request) {
        classService.addClass(classDTO, request);
        return Result.success();
    }

    /**
     * 更新班级信息接口
     * @param classDTO 班级信息DTO，包含需要更新的班级ID和字段
     * @param request HTTP请求对象，用于获取会话信息
     * @return 空Result对象表示操作成功
     * @throws BusinessException 如果班级不存在或用户无权限会抛出异常
     * @apiNote 仅管理员可访问
     */
    @PutMapping("/update")
    @ApiOperation(value = "更新班级信息", notes = "更新指定班级的基本信息，仅管理员可访问")
    public Result<Void> updateClass(@RequestBody ClassDTO classDTO, HttpServletRequest request) {
        classService.updateClass(classDTO, request);
        return Result.success();

    }

    /**
     * 删除班级接口
     * @param id 要删除的班级ID
     * @param request HTTP请求对象，用于获取会话信息
     * @return 空Result对象表示操作成功
     * @throws BusinessException 如果班级不存在、班级中还有学生、或用户无权限会抛出异常
     * @apiNote 仅管理员可访问，删除班级前需确保班级中没有关联的学生
     */
    @DeleteMapping("/delete/{id}")
    @ApiOperation(value = "删除班级", notes = "根据ID删除班级，仅管理员可访问")
    public Result<Void> deleteClassById(@PathVariable Integer id, HttpServletRequest request) {
        classService.deleteClassById(id, request);
        return Result.success();
    }

    /**
     * 根据ID获取班级详情接口
     * @param id 班级ID
     * @return 包含班级详细信息的Result对象
     * @throws BusinessException 如果班级不存在会抛出异常
     * @apiNote 返回的班级信息包含学生列表
     */
    @GetMapping("/{id}")
    @ApiOperation(value = "获取班级详情", notes = "根据班级ID获取班级详细信息，包括学生列表")
    public Result<ClassVO> getClassById(@PathVariable Integer id) {
        ClassVO clazz = classService.getClassById(id);
        return Result.success(clazz);
    }

    /**
     * 获取班级学生数量接口
     * @param id 班级ID
     * @return 包含学生数量的Result对象
     * @throws BusinessException 如果班级不存在会抛出异常
     * @apiNote 返回的是该班级当前的学生总数
     */
    @GetMapping("/get/stuCount/{id}")
    @ApiOperation(value = "获取班级学生数量", notes = "根据班级ID统计该班级的学生人数")
    public Result<Integer> getStuCountByClass(@PathVariable Integer id) {
        classService.getStuCountByClassId(id);
        return Result.success(1);
    }

    /**
     * 根据教师ID获取班级列表接口
     * @param teacherId 教师ID
     * @param request HTTP请求对象，用于获取会话信息
     * @return 包含班级列表的Result对象
     * @throws BusinessException 如果教师ID为空会抛出异常
     * @apiNote 返回的班级列表包含基本信息但不包含学生详情
     */
    @GetMapping("/get/byTeacher")
    @ApiOperation(value = "根据教师ID获取班级", notes = "根据教师ID查询该教师负责的所有班级列表")
    public Result<List<ClassVO>> getClassByTeacherId(@RequestParam("teacherId") Integer teacherId, HttpServletRequest request) {
        // 非空判断
        if (teacherId == null) {
            throw new BusinessException(ErrorCode.PRIMARY_ERROR);
        }
        List<ClassVO> classVOList = classService.getClassByTeacherId(teacherId, request);
        return Result.success(classVOList);
    }


    /**
     * 批量添加学生到班级接口
     * @param classAddStudentsRequest 包含学生ID列表和目标班级ID的请求对象
     * @param request HTTP请求对象，用于获取会话信息
     * @return 包含操作影响记录数的Result对象
     * @throws BusinessException 如果班级或学生不存在，或用户无权限会抛出异常
     * @apiNote 仅管理员可访问，会覆盖学生原有的班级关系
     */
    @PostMapping("/add/students")
    @ApiOperation(value = "批量添加学生到班级", notes = "将多个学生添加到指定班级，仅管理员可访问")
    public Result<Integer> addStudentsByClass(@RequestBody ClassAddStudentsRequest classAddStudentsRequest, HttpServletRequest request) {
        // 非空判断
        if (classAddStudentsRequest.getStudentIds() == null || CollUtil.isEmpty(classAddStudentsRequest.getStudentIds()) || classAddStudentsRequest.getClassId() == null) {
            throw new BusinessException(ErrorCode.PRIMARY_ERROR);
        }
        // 权限校验
        User loginUser = userService.getLoginUser(request);
        if (!userService.isCompareRole(loginUser, UserRoleEnum.ADMIN.getKey())) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR, "仅管理员可用");
        }
        int i = classService.addStudentsByClass(classAddStudentsRequest.getStudentIds(), classAddStudentsRequest.getClassId());
        return Result.success(i);
    }


    /**
     * 获取未选择任何班级的学生列表接口
     * @param request HTTP请求对象，用于获取会话信息
     * @return 包含未选课学生列表的Result对象
     * @throws BusinessException 如果用户无权限会抛出异常
     * @apiNote 仅管理员可访问，返回的学生列表不包含已选课学生
     */
    @GetMapping("/list/student/noneClass")
    @ApiOperation(value = "获取未选班级学生列表", notes = "获取系统中尚未选择任何班级的学生列表，仅管理员可访问")
    public Result<List<UserVO>> getStudentListDontSelectClass(HttpServletRequest request) {
        // 权限校验
        User loginUser = userService.getLoginUser(request);
        if (!userService.isCompareRole(loginUser, UserRoleEnum.ADMIN.getKey())) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR, "仅管理员可用");
        }
        List<UserVO> studentList = classService.getStudentListDontSelectClass(request);
        return Result.success(studentList);
    }


    /**
     * 获取所有热门计算机专业列表接口
     * @return 包含专业名称列表的Result对象
     * @apiNote 返回的是预定义的热门计算机专业列表
     */
    @GetMapping("/get/major")
    @ApiOperation(value = "获取所有热门计算机专业列表", notes = "获取系统预定义的热门计算机专业名称列表")
    public Result<List<String>> getAllMajor() {
        List<String> hotComputerMajors = Arrays.asList(
                "人工智能",       // Artificial Intelligence
                "机器学习",       // Machine Learning
                "数据科学",       // Data Science
                "软件工程",       // Software Engineering
                "网络安全",       // Cybersecurity
                "云计算",         // Cloud Computing
                "物联网",         // Internet of Things (IoT)
                "区块链技术",     // Blockchain Technology
                "虚拟现实",       // Virtual Reality
                "增强现实"        // Augmented Reality
        );
        return Result.success(hotComputerMajors);
    }

}